/*
 * FreenectAdaptee.h
 *
 */

#ifndef FREENECTADAPTEE_H_
#define FREENECTADAPTEE_H_

#include <libfreenect.hpp>
#include <iostream>
#include <vector>
#include <cmath>
#include <pthread.h>
#include <opencv/cv.h>
#include <opencv/cxcore.h>
#include <opencv/highgui.h>

namespace libfreenect {

/**
 * \class FreenectAdaptee
 * @brief 
 * @details
 * @date May 25, 2012
 * @author Gennaro Capo
 * @author Mirko Conte
 * @author Vincenzo De Notaris
 * @author Roberto Pacilio
 * @version 1.0
 * @namespace libfreenect
 * @see Freenect::FreenectDevice
 */
class FreenectAdaptee : public Freenect::FreenectDevice {

public:

	/**
	 * Costruttore della classe FreenectApdatee.
	 */
	FreenectAdaptee(freenect_context *_ctx, int _index);

	/**
	 * Distruttore della classe FreenectAdaptee.
	 */
	~FreenectAdaptee();

	/**
	 *
	 * @param _rgb
	 * @param timestamp
	 */
	void VideoCallback(void* _rgb, uint32_t timestamp);

	/**
	 *
	 * @param _depth
	 * @param timestamp
	 */
	void DepthCallback(void* _depth, uint32_t timestamp);

	/**
	 *
	 * @param output
	 * @return
	 */
	bool getVideo(cv::Mat &dest);

	/**
	 *
	 * @param output
	 * @return
	 */
	bool getDepth(cv::Mat &dest);

private:

	/*
	 * Previene dalla costruzione mediante copia.
	 */
	FreenectAdaptee(const FreenectAdaptee&);

	/*
	 * Previene l'assegnamento.
	 */
	FreenectAdaptee& operator = (const FreenectAdaptee&);

	/*
	 * Inner-class FreenectMutex. Rappresenta una struttura dati mutex associata ad un FreenectDevice.
	 */
	class FreenectMutex {

	public:

		/*
		 * Costruttore della classe FreenectMutex.
		 */
		FreenectMutex();

		/*
		 * Distruttore della classe FreenectMutex.
		 */
		~FreenectMutex();

		/*
		 * Metodo per il lock del mutex.
		 */
		void lock();

		/*
		 * Metodo per l'unlock del mutex.
		 */
		void unlock();

		pthread_mutex_t *_m_mutex;

	};

	std::vector<uint8_t> _m_buffer_rgb;
	std::vector<uint8_t> _m_buffer_depth;
	std::vector<uint16_t> _m_gamma;
	cv::Mat _rgbMat;
	cv::Mat _depthMat;
	cv::Mat _ownMat;
	FreenectMutex *_m_rgb_mutex;
	FreenectMutex *_m_depth_mutex;
	bool _m_new_rgb_frame;
	bool _m_new_depth_frame;

};

} /* namespace libfreenect */
#endif /* FREENECTADAPTEE_H_ */
